package com.cencat.route.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cencat.common.result.Result;
import com.cencat.route.entity.Driver;
import com.cencat.route.service.DriverService;
import com.cencat.route.vo.DriverQueryVO;
import com.cencat.route.vo.DriverStatisticsVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.List;

/**
 * 司机管理控制器
 * 
 * @author cencat
 * @since 2024-01-01
 */
@Slf4j
@RestController
@RequestMapping("/api/route/driver")
@RequiredArgsConstructor
@Tag(name = "司机管理", description = "司机信息的增删改查和业务操作")
public class DriverController {

    private final DriverService driverService;

    @GetMapping("/page")
    @Operation(summary = "分页查询司机", description = "根据条件分页查询司机信息")
    public Result<Page<Driver>> getDriverPage(
            @Parameter(description = "页码", example = "1") @RequestParam(defaultValue = "1") Long current,
            @Parameter(description = "每页大小", example = "10") @RequestParam(defaultValue = "10") Long size,
            @Parameter(description = "查询条件") DriverQueryVO query) {
        try {
            Page<Driver> page = new Page<>(current, size);
            Page<Driver> result = driverService.selectDriverPage(page, query);
            return Result.success(result);
        } catch (Exception e) {
            log.error("分页查询司机失败: {}", e.getMessage(), e);
            return Result.error("分页查询司机失败: " + e.getMessage());
        }
    }

    @GetMapping("/list")
    @Operation(summary = "查询司机列表", description = "根据条件查询司机列表")
    public Result<List<Driver>> getDriverList(@Parameter(description = "查询条件") DriverQueryVO query) {
        try {
            List<Driver> result = driverService.selectDriverList(query);
            return Result.success(result);
        } catch (Exception e) {
            log.error("查询司机列表失败: {}", e.getMessage(), e);
            return Result.error("查询司机列表失败: " + e.getMessage());
        }
    }

    @GetMapping("/{id}")
    @Operation(summary = "根据ID查询司机", description = "根据司机ID查询详细信息")
    public Result<Driver> getDriverById(@Parameter(description = "司机ID") @PathVariable Long id) {
        try {
            Driver driver = driverService.getById(id);
            if (driver == null) {
                return Result.error("司机不存在");
            }
            return Result.success(driver);
        } catch (Exception e) {
            log.error("查询司机详情失败: {}", e.getMessage(), e);
            return Result.error("查询司机详情失败: " + e.getMessage());
        }
    }

    @PostMapping
    @Operation(summary = "新增司机", description = "创建新的司机信息")
    public Result<Boolean> createDriver(@Parameter(description = "司机信息") @Valid @RequestBody Driver driver) {
        try {
            boolean result = driverService.save(driver);
            return result ? Result.success(true) : Result.error("新增司机失败");
        } catch (Exception e) {
            log.error("新增司机失败: {}", e.getMessage(), e);
            return Result.error("新增司机失败: " + e.getMessage());
        }
    }

    @PutMapping
    @Operation(summary = "更新司机", description = "更新司机信息")
    public Result<Boolean> updateDriver(@Parameter(description = "司机信息") @Valid @RequestBody Driver driver) {
        try {
            boolean result = driverService.updateById(driver);
            return result ? Result.success(true) : Result.error("更新司机失败");
        } catch (Exception e) {
            log.error("更新司机失败: {}", e.getMessage(), e);
            return Result.error("更新司机失败: " + e.getMessage());
        }
    }

    @DeleteMapping("/{id}")
    @Operation(summary = "删除司机", description = "根据ID删除司机")
    public Result<Boolean> deleteDriver(@Parameter(description = "司机ID") @PathVariable Long id) {
        try {
            boolean result = driverService.removeById(id);
            return result ? Result.success(true) : Result.error("删除司机失败");
        } catch (Exception e) {
            log.error("删除司机失败: {}", e.getMessage(), e);
            return Result.error("删除司机失败: " + e.getMessage());
        }
    }

    @PutMapping("/batch/status")
    @Operation(summary = "批量更新司机状态", description = "批量更新司机状态")
    public Result<Boolean> batchUpdateDriverStatus(
            @Parameter(description = "司机ID列表") @RequestBody List<Long> ids,
            @Parameter(description = "状态") @RequestParam String status,
            @Parameter(description = "更新人ID") @RequestParam Long updatedBy) {
        try {
            boolean result = driverService.batchUpdateDriverStatus(ids, status, updatedBy);
            return result ? Result.success(true) : Result.error("批量更新司机状态失败");
        } catch (Exception e) {
            log.error("批量更新司机状态失败: {}", e.getMessage(), e);
            return Result.error("批量更新司机状态失败: " + e.getMessage());
        }
    }

    @PutMapping("/batch/credit-score")
    @Operation(summary = "批量更新信用分数", description = "批量更新司机信用分数")
    public Result<Boolean> batchUpdateCreditScore(
            @Parameter(description = "司机ID列表") @RequestBody List<Long> ids,
            @Parameter(description = "信用分数") @RequestParam BigDecimal creditScore,
            @Parameter(description = "更新人ID") @RequestParam Long updatedBy) {
        try {
            boolean result = driverService.batchUpdateCreditScore(ids, creditScore, updatedBy);
            return result ? Result.success(true) : Result.error("批量更新信用分数失败");
        } catch (Exception e) {
            log.error("批量更新信用分数失败: {}", e.getMessage(), e);
            return Result.error("批量更新信用分数失败: " + e.getMessage());
        }
    }

    @PutMapping("/batch/location")
    @Operation(summary = "批量更新位置信息", description = "批量更新司机位置信息")
    public Result<Boolean> batchUpdateLocation(
            @Parameter(description = "司机ID列表") @RequestBody List<Long> ids,
            @Parameter(description = "纬度") @RequestParam BigDecimal latitude,
            @Parameter(description = "经度") @RequestParam BigDecimal longitude,
            @Parameter(description = "更新人ID") @RequestParam Long updatedBy) {
        try {
            boolean result = driverService.batchUpdateLocation(ids, latitude, longitude, updatedBy);
            return result ? Result.success(true) : Result.error("批量更新位置信息失败");
        } catch (Exception e) {
            log.error("批量更新位置信息失败: {}", e.getMessage(), e);
            return Result.error("批量更新位置信息失败: " + e.getMessage());
        }
    }

    @GetMapping("/statistics")
    @Operation(summary = "获取司机统计信息", description = "获取司机相关统计数据")
    public Result<DriverStatisticsVO> getDriverStatistics() {
        try {
            DriverStatisticsVO result = driverService.getDriverStatistics();
            return Result.success(result);
        } catch (Exception e) {
            log.error("获取司机统计信息失败: {}", e.getMessage(), e);
            return Result.error("获取司机统计信息失败: " + e.getMessage());
        }
    }

    @PostMapping("/smart-match")
    @Operation(summary = "智能匹配司机", description = "根据条件智能匹配合适的司机")
    public Result<String> smartMatchDrivers(
            @Parameter(description = "匹配条件") @RequestParam String matchCriteria,
            @Parameter(description = "最大匹配数量") @RequestParam(defaultValue = "10") Integer maxMatches) {
        try {
            String result = driverService.smartMatchDrivers(matchCriteria, maxMatches);
            return Result.success(result);
        } catch (Exception e) {
            log.error("智能匹配司机失败: {}", e.getMessage(), e);
            return Result.error("智能匹配司机失败: " + e.getMessage());
        }
    }

    @GetMapping("/nearby")
    @Operation(summary = "查询附近司机", description = "根据位置查询附近的司机")
    public Result<List<Driver>> getNearbyDrivers(
            @Parameter(description = "纬度") @RequestParam BigDecimal latitude,
            @Parameter(description = "经度") @RequestParam BigDecimal longitude,
            @Parameter(description = "搜索半径(公里)") @RequestParam BigDecimal radius,
            @Parameter(description = "限制数量") @RequestParam(defaultValue = "20") Integer limit) {
        try {
            List<Driver> result = driverService.getNearbyDrivers(latitude, longitude, radius, limit);
            return Result.success(result);
        } catch (Exception e) {
            log.error("查询附近司机失败: {}", e.getMessage(), e);
            return Result.error("查询附近司机失败: " + e.getMessage());
        }
    }

    @GetMapping("/available")
    @Operation(summary = "获取可用司机列表", description = "获取当前可用的司机列表")
    public Result<List<Driver>> getAvailableDrivers(
            @Parameter(description = "限制数量") @RequestParam(defaultValue = "50") Integer limit) {
        try {
            List<Driver> result = driverService.getAvailableDrivers(limit);
            return Result.success(result);
        } catch (Exception e) {
            log.error("获取可用司机列表失败: {}", e.getMessage(), e);
            return Result.error("获取可用司机列表失败: " + e.getMessage());
        }
    }

    @GetMapping("/active")
    @Operation(summary = "获取活跃司机列表", description = "获取活跃的司机列表")
    public Result<List<Driver>> getActiveDrivers(
            @Parameter(description = "限制数量") @RequestParam(defaultValue = "50") Integer limit) {
        try {
            List<Driver> result = driverService.getActiveDrivers(limit);
            return Result.success(result);
        } catch (Exception e) {
            log.error("获取活跃司机列表失败: {}", e.getMessage(), e);
            return Result.error("获取活跃司机列表失败: " + e.getMessage());
        }
    }

    @GetMapping("/high-rating")
    @Operation(summary = "获取高评分司机列表", description = "获取评分较高的司机列表")
    public Result<List<Driver>> getHighRatingDrivers(
            @Parameter(description = "最低评分") @RequestParam(defaultValue = "4.5") BigDecimal minRating,
            @Parameter(description = "限制数量") @RequestParam(defaultValue = "30") Integer limit) {
        try {
            List<Driver> result = driverService.getHighRatingDrivers(minRating, limit);
            return Result.success(result);
        } catch (Exception e) {
            log.error("获取高评分司机列表失败: {}", e.getMessage(), e);
            return Result.error("获取高评分司机列表失败: " + e.getMessage());
        }
    }

    @GetMapping("/verified")
    @Operation(summary = "获取已认证司机列表", description = "获取已通过认证的司机列表")
    public Result<List<Driver>> getVerifiedDrivers(
            @Parameter(description = "限制数量") @RequestParam(defaultValue = "50") Integer limit) {
        try {
            List<Driver> result = driverService.getVerifiedDrivers(limit);
            return Result.success(result);
        } catch (Exception e) {
            log.error("获取已认证司机列表失败: {}", e.getMessage(), e);
            return Result.error("获取已认证司机列表失败: " + e.getMessage());
        }
    }

    @GetMapping("/new")
    @Operation(summary = "获取新注册司机列表", description = "获取最近注册的司机列表")
    public Result<List<Driver>> getNewDrivers(
            @Parameter(description = "天数") @RequestParam(defaultValue = "7") Integer days,
            @Parameter(description = "限制数量") @RequestParam(defaultValue = "30") Integer limit) {
        try {
            List<Driver> result = driverService.getNewDrivers(days, limit);
            return Result.success(result);
        } catch (Exception e) {
            log.error("获取新注册司机列表失败: {}", e.getMessage(), e);
            return Result.error("获取新注册司机列表失败: " + e.getMessage());
        }
    }

    @GetMapping("/check/exists/{id}")
    @Operation(summary = "检查司机是否存在", description = "根据ID检查司机是否存在")
    public Result<Boolean> checkDriverExists(@Parameter(description = "司机ID") @PathVariable Long id) {
        try {
            boolean result = driverService.checkDriverExists(id);
            return Result.success(result);
        } catch (Exception e) {
            log.error("检查司机是否存在失败: {}", e.getMessage(), e);
            return Result.error("检查司机是否存在失败: " + e.getMessage());
        }
    }

    @GetMapping("/check/phone")
    @Operation(summary = "检查手机号是否存在", description = "检查手机号是否已被使用")
    public Result<Boolean> checkPhoneExists(
            @Parameter(description = "手机号") @RequestParam String phone,
            @Parameter(description = "排除的司机ID") @RequestParam(required = false) Long excludeId) {
        try {
            boolean result = driverService.checkPhoneExists(phone, excludeId);
            return Result.success(result);
        } catch (Exception e) {
            log.error("检查手机号是否存在失败: {}", e.getMessage(), e);
            return Result.error("检查手机号是否存在失败: " + e.getMessage());
        }
    }

    @GetMapping("/check/license")
    @Operation(summary = "检查驾驶证号是否存在", description = "检查驾驶证号是否已被使用")
    public Result<Boolean> checkLicenseNumberExists(
            @Parameter(description = "驾驶证号") @RequestParam String licenseNumber,
            @Parameter(description = "排除的司机ID") @RequestParam(required = false) Long excludeId) {
        try {
            boolean result = driverService.checkLicenseNumberExists(licenseNumber, excludeId);
            return Result.success(result);
        } catch (Exception e) {
            log.error("检查驾驶证号是否存在失败: {}", e.getMessage(), e);
            return Result.error("检查驾驶证号是否存在失败: " + e.getMessage());
        }
    }

    @PostMapping("/register")
    @Operation(summary = "司机注册", description = "新司机注册")
    public Result<Boolean> registerDriver(
            @Parameter(description = "司机信息") @Valid @RequestBody Driver driver,
            @Parameter(description = "注册人ID") @RequestParam Long registeredBy) {
        try {
            boolean result = driverService.registerDriver(driver, registeredBy);
            return result ? Result.success(true) : Result.error("司机注册失败");
        } catch (Exception e) {
            log.error("司机注册失败: {}", e.getMessage(), e);
            return Result.error("司机注册失败: " + e.getMessage());
        }
    }

    @PutMapping("/verify/{id}")
    @Operation(summary = "司机认证", description = "对司机进行认证")
    public Result<Boolean> verifyDriver(
            @Parameter(description = "司机ID") @PathVariable Long id,
            @Parameter(description = "认证状态") @RequestParam String verificationStatus,
            @Parameter(description = "认证备注") @RequestParam(required = false) String verificationNotes,
            @Parameter(description = "认证人ID") @RequestParam Long verifiedBy) {
        try {
            boolean result = driverService.verifyDriver(id, verificationStatus, verificationNotes, verifiedBy);
            return result ? Result.success(true) : Result.error("司机认证失败");
        } catch (Exception e) {
            log.error("司机认证失败: {}", e.getMessage(), e);
            return Result.error("司机认证失败: " + e.getMessage());
        }
    }

    @PutMapping("/activate/{id}")
    @Operation(summary = "激活司机", description = "激活司机账户")
    public Result<Boolean> activateDriver(
            @Parameter(description = "司机ID") @PathVariable Long id,
            @Parameter(description = "激活人ID") @RequestParam Long activatedBy) {
        try {
            boolean result = driverService.activateDriver(id, activatedBy);
            return result ? Result.success(true) : Result.error("激活司机失败");
        } catch (Exception e) {
            log.error("激活司机失败: {}", e.getMessage(), e);
            return Result.error("激活司机失败: " + e.getMessage());
        }
    }

    @PutMapping("/deactivate/{id}")
    @Operation(summary = "停用司机", description = "停用司机账户")
    public Result<Boolean> deactivateDriver(
            @Parameter(description = "司机ID") @PathVariable Long id,
            @Parameter(description = "停用原因") @RequestParam String reason,
            @Parameter(description = "停用人ID") @RequestParam Long deactivatedBy) {
        try {
            boolean result = driverService.deactivateDriver(id, reason, deactivatedBy);
            return result ? Result.success(true) : Result.error("停用司机失败");
        } catch (Exception e) {
            log.error("停用司机失败: {}", e.getMessage(), e);
            return Result.error("停用司机失败: " + e.getMessage());
        }
    }

    @PutMapping("/update-location/{id}")
    @Operation(summary = "更新司机位置", description = "更新司机当前位置信息")
    public Result<Boolean> updateDriverLocation(
            @Parameter(description = "司机ID") @PathVariable Long id,
            @Parameter(description = "纬度") @RequestParam BigDecimal latitude,
            @Parameter(description = "经度") @RequestParam BigDecimal longitude,
            @Parameter(description = "更新人ID") @RequestParam Long updatedBy) {
        try {
            boolean result = driverService.updateDriverLocation(id, latitude, longitude, updatedBy);
            return result ? Result.success(true) : Result.error("更新司机位置失败");
        } catch (Exception e) {
            log.error("更新司机位置失败: {}", e.getMessage(), e);
            return Result.error("更新司机位置失败: " + e.getMessage());
        }
    }

    @PutMapping("/update-credit/{id}")
    @Operation(summary = "更新信用分数", description = "更新司机信用分数")
    public Result<Boolean> updateCreditScore(
            @Parameter(description = "司机ID") @PathVariable Long id,
            @Parameter(description = "信用分数") @RequestParam BigDecimal creditScore,
            @Parameter(description = "更新原因") @RequestParam(required = false) String reason,
            @Parameter(description = "更新人ID") @RequestParam Long updatedBy) {
        try {
            boolean result = driverService.updateCreditScore(id, creditScore, reason, updatedBy);
            return result ? Result.success(true) : Result.error("更新信用分数失败");
        } catch (Exception e) {
            log.error("更新信用分数失败: {}", e.getMessage(), e);
            return Result.error("更新信用分数失败: " + e.getMessage());
        }
    }

}